#import "DetailViewController+ChangeAisleSheet.h"
#import "NSValueTransformer+SRAdditions.h"
#import "RNAisle.h"
#import "RNItem.h"
#import "RNListItem.h"
#import "RNEditViewController.h"
#import "NSManagedObjectContext+SRAdditions.h"
#import "NSTreeController+SRAdditions.h"
#import "RNConstants.h"


#pragma mark -
@interface RNAislesSetToStringTransformer : NSValueTransformer 
@end

@implementation RNAislesSetToStringTransformer
+ (BOOL)allowsReverseTransformation {
    return NO;
}
+ (Class)transformedValueClass {
    return [NSString class];
}
- (id)transformedValue:(id)value {
    if (![value respondsToSelector:@selector(count)])
        return nil;
    NSString *countString = [value count] == 0 ? @"No" : [NSString stringWithFormat:@"%i", [value count]];
    NSString *aislesString = [value count] == 1 ? @"aisle" : @"aisles";
    return [NSString stringWithFormat:@"%@ %@", countString, aislesString];
}
@end

#pragma mark -
@implementation DetailViewController (ChangeAisleSheet)

-(IBAction)changeAisleForSelectedItems:(id)sender {
    NSArray *selectedItems = [[self detailTreeController] selectedObjects];
    NSMutableSet *commonAisles = nil;
    for (id item in selectedItems) {
        if (!commonAisles) {
            commonAisles = [[item aisles] mutableCopy];
            continue;
        }
        [commonAisles intersectSet:[item aisles]];
    }
    RNStore *selectedStore = [self storeFilter];
    if (selectedStore)
        [commonAisles filterUsingPredicate:[NSPredicate predicateWithFormat:@"store == %@", selectedStore]];
    RNAisle *commonAisle = [commonAisles count] > 0 ? [commonAisles anyObject] : nil;
    if (!selectedStore)
        selectedStore = (RNStore *)[commonAisle store];
    
    NSWindow *sheet = [self changeAisleSheet];
    [self setItemsToChange:selectedItems];
    [self setSheetTitle:[self buildSheetTitleFromArray:[selectedItems valueForKeyPath:@"title"]]];
    if (commonAisle) {
        [[self storesController] performSelector:@selector(setSelectedObjects:) withObject:[NSArray arrayWithObject:selectedStore] afterDelay:0];
        [[self aislesController] performSelector:@selector(setSelectedObjects:) withObject:[NSArray arrayWithObject:commonAisle] afterDelay:0];
    }
//    editItem = [[self editViewController] editingItem];
    [NSApp beginSheet:sheet modalForWindow:[NSApp mainWindow] modalDelegate:self didEndSelector:@selector(changeAisleSheetDidEnd:returnCode:contextInfo:) contextInfo:nil];
}

-(IBAction)changeAisleForEditingItem:(id)sender {
    NSWindow *sheet = [self changeAisleSheet];
    [self setItemsToChange:[NSArray arrayWithObject:[[self editViewController] editingItem]]];
    [self setSheetTitle:[[[self editViewController] editingItem] title]];

    NSInteger selectionIndex = [sender indexOfSelectedItem] - 1;
    NSArray *allStores = [[self managedObjectContext] fetchObjectsForEntityName:RNEntityNameStore withPredicate:nil];
    allStores = [allStores sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES]]];
    RNStore *selectedStore = [allStores objectAtIndex:selectionIndex];
    NSArray *itemAisles = [[[self editViewController] aislesController] arrangedObjects];
    NSArray *itemStores = [itemAisles valueForKey:@"store"];
    NSInteger storeIndex = [itemStores indexOfObject:selectedStore];
    RNAisle *selectedAisle = storeIndex == NSNotFound ? nil : [itemAisles objectAtIndex:storeIndex];
    [[self storesController] performSelector:@selector(setSelectedObjects:) withObject:[NSArray arrayWithObject:selectedStore] afterDelay:0];
    if (selectedAisle)
        [[self aislesController] performSelector:@selector(setSelectedObjects:) withObject:[NSArray arrayWithObject:selectedAisle] afterDelay:0];
    
//    editItem = [[self editViewController] editingItem];
    [NSApp beginSheet:sheet modalForWindow:[NSApp mainWindow] modalDelegate:self didEndSelector:@selector(changeAisleSheetDidEnd:returnCode:contextInfo:) contextInfo:nil];
//    [NSApp beginSheet:sheet modalForWindow:[NSApp mainWindow] modalDelegate:self didEndSelector:@selector(changeAisleSheetFromEditingItemDidEnd:returnCode:contextInfo:) contextInfo:nil];
}

-(void)changeAisleSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
//    if (editItem) {
//        NSTreeNode *editNode = [[self detailTreeController] treeNodeForObject:editItem];
//        editItem = nil;
//        NSInteger rowIndex = [[self detailView] rowForItem:editNode];
//        if (rowIndex != -1)
//            [self showEditItemViewAtRow:rowIndex];
//    }
    [sheet orderOut:self];
}

-(void)changeAisleSheetFromEditingItemDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
    [sheet orderOut:self];
    id editItem = [[self itemsToChange] objectAtIndex:0];
    if (!editItem)
        return;
    NSTreeNode *itemNode = [[self detailTreeController] treeNodeForObject:editItem];
    NSInteger rowIndex = [[self detailView] rowForItem:itemNode];
    [self showEditItemViewAtRow:rowIndex];
}

-(IBAction)cancelChangeAisleSheet:(id)sender {
    [NSApp endSheet:[self changeAisleSheet]];
}

-(IBAction)changeItemAisle:(id)sender {
    [NSApp endSheet:[self changeAisleSheet]];
    RNAisle *selectedAisle = [[[self aislesController] selectedObjects] objectAtIndex:0];
    
    // Replace old aisles in the selected store
    [[self itemsToChange] enumerateObjectsUsingBlock:^(id object, NSUInteger itemIndex, BOOL *stop) {
        NSSet *oldAisles = [[object valueForKeyPath:@"aisles"] filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"store == %@", [selectedAisle store]]];
        [object removeAisles:oldAisles];
        [object addAislesObject:selectedAisle];
        if ([object isKindOfClass:[RNItem class]]) {
            [[object listItems] makeObjectsPerformSelector:@selector(removeAisles:) withObject:oldAisles];
            [[object listItems] makeObjectsPerformSelector:@selector(addAislesObject:) withObject:selectedAisle];
        }
        if ([object isKindOfClass:[RNListItem class]]) {
            [[object item] removeAisles:oldAisles];
            [[object item] addAislesObject:selectedAisle];
        }
    }];
}

-(NSWindow *)changeAisleSheet {
    if (!changeAisleSheet_) {
        [[[RNAislesSetToStringTransformer alloc] init] registerTransformerWithClassName];
        NSAssert([NSBundle loadNibNamed:@"ChangeAisleSheet" owner:self], @"DetailViewController:changeAisleSheet: error loading nib");
        [[[self changeAisleTitleField] cell] setBackgroundStyle:NSBackgroundStyleRaised];
    }
    return changeAisleSheet_;
}

@end
